import MySQLdb
from AccessControl import ClassSecurityInfo
from Products.KnowledgeEngine.Utils.CallbackIterator import CallbackIterator, buildDict
from Products.KnowledgeEngine.Utils.OrderedDict import OrderedDict

def qstr(string, quote=True):
    """ 
        Wrapper function to quote a string for safe MySQL use
    """
    if string is None: return "NULL"
    
    if quote:
        if quote is True: quote = '"'
        
        return "%s%s%s" % (quote, MySQLdb.escape_string(str(string)), quote)
    else:
        return MySQLdb.escape_string(str(string))
    
# ---------------------------------------------------------------    
    
def qlist(theList, quote=True):
    """ Quotes all elements in a list and returns as comma seperated values """
    
    cleanList = []
    for item in theList:
        clean = qstr(item, quote=quote)
        cleanList.append( clean )
        
    return ",".join( cleanList )        
        

def qobject(object, quote=True):
    """ Quotes the specified object """
    
    if type(object) is list:
        return qlist( object, quote )
    elif type(object) in (str, unicode, int, float, complex):
        return qstr( object, quite )
    
    

class MySQLMixin: 
    
    security = ClassSecurityInfo()
                    
    security.declareProtected('execute', "Manage portal")
    def execute(self, query, max_rows=0, REQUEST=None):
        """
            Executes the specified SQL query, returning the 
            resultset
            
            This is used for backwards compatibility with older 
            KE functions that expect tuple results. Further
            development should use sqlQuery(), which returns
            a list of dictionaries and makes for much cleaner code.
            
        """               
        
        # Don't allow execute to be called directly via HTTP
        if REQUEST:
            raise Unauthorized

        try:
            connection = self.getDatabaseConnection()

            #log.debug("%s:(%d): %s" % (sys._getframe().f_code.co_name, sys._getframe().f_lineno, query))

            description, rs = connection.query( query, max_rows=max_rows)
            
        except Exception, e:
            print "Error executing query: '%s'" % str(e)
            print query
            print "-------------------- END SQL"
            raise
        
        return rs
    
    # -------------------------------------------------------------------------        
        
    security.declareProtected('sqlQuery', "Manage portal")        
    def sqlQuery( self, query ):
        
        connection = self.getDatabaseConnection()

        # Log SQL statement in debug mode
        #log.debug("%s:(%d): %s" % (sys._getframe().f_code.co_name, sys._getframe().f_lineno, query))
        #print query
        desc, results = connection.query( query, max_rows = 0 )
        
        # Was this an INSERT/UPDATE Query?
        if not desc:
            # Get the insert id, if any
            if type(results) is tuple:
                insert_id = connection.db.insert_id()
            else:
                insert_id = results.lastrowid

            return insert_id
            
        cb = CallbackIterator( results, lambda row: buildDict( row, desc ))
        
        return cb    
    
    #---------------------------------------------------------------#                        
    
    security.declarePublic('qstring')
    def qstring(self, string, quote=True):
        """ Quote a string (Wrap qstr for use within Restricted Python Scripts """ 
        
        return qstr(string=string, quote=quote)
        
    #---------------------------------------------------------------#
            
    security.declarePublic('qlist')
    def qlist(self, items, quote=True):
        """ Quote a string (Wrap qstr for use within Restricted Python Scripts """ 
        
        return qlist(items, quote=quote)
        
    #---------------------------------------------------------------#
                        
    security.declarePublic('qobject')
    def qobject(self, object, quote=True):
        """ Quote a string (Wrap qstr for use within Restricted Python Scripts """ 
        
        return qobject(object, quote=quote)
        
    #---------------------------------------------------------------#     